# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt

import frappe
from frappe import _
from erpnext.accounts.report.financial_statements import (
    get_period_list,
    get_columns,
    get_data
)
from erpnext.accounts.report.financial_statements import get_cost_centers_with_children

def get_financial_statements_cn(company, period_start_date, period_end_date, fiscal_year,
                              periodicity="Monthly", compare_with_previous_year=False,
                              compare_with_budget=False, budget=None, cost_center=None):
    """生成带有同比和预算比较列的财务报表数据"""
    # 使用 frappe._dict 确保过滤器支持属性访问
    base_filters = frappe._dict({
        "company": company
    })
    
    # 处理成本中心子节点
    if cost_center:
        base_filters.cost_center = get_cost_centers_with_children(cost_center)
    
    # 获取期间列表
    period_list = get_period_list(
        period_start_date=period_start_date,
        period_end_date=period_end_date,
        periodicity=periodicity,
        company=company,
        from_fiscal_year=fiscal_year,
        to_fiscal_year=fiscal_year,
        filter_based_on="Fiscal Year"
    )
    
    # 确定是否需要比较列
    has_prev_year = compare_with_previous_year
    has_budget = compare_with_budget and budget
    
    # 获取收入数据
    income_data = get_data(
        company=company,
        root_type="Income",
        balance_must_be="Credit",
        period_list=period_list,
        filters=base_filters,
        accumulated_values=1,
        ignore_closing_entries=True,
    )
    
    # 获取支出数据
    expense_data = get_data(
        company=company,
        root_type="Expense",
        balance_must_be="Debit",
        period_list=period_list,
        filters=base_filters,
        accumulated_values=1,
        ignore_closing_entries=True,
    )
    
    data = []
    data.extend(income_data or [])
    data.extend(expense_data or [])
    
    # 处理同比数据
    if has_prev_year:
        prev_year_start, prev_year_end = get_prev_year_period(
            period_start_date, period_end_date
        )
        
        prev_fiscal_year = str(int(fiscal_year) - 1)
        prev_year_period_list = get_period_list(
            period_start_date=prev_year_start,
            period_end_date=prev_year_end,
            periodicity=periodicity,
            company=company,
            from_fiscal_year=prev_fiscal_year,
            to_fiscal_year=prev_fiscal_year,
            filter_based_on="Fiscal Year"
        )
        
        prev_year_income = get_data(
            company=company,
            root_type="Income",
            balance_must_be="Credit",
            period_list=prev_year_period_list,
            filters=base_filters,
            accumulated_values=1,
            ignore_closing_entries=True,
        )
        
        prev_year_expense = get_data(
            company=company,
            root_type="Expense",
            balance_must_be="Debit",
            period_list=prev_year_period_list,
            filters=base_filters,
            accumulated_values=1,
            ignore_closing_entries=True,
        )
        
        prev_year_data = []
        prev_year_data.extend(prev_year_income or [])
        prev_year_data.extend(prev_year_expense or [])
        
        # 合并同比数据
        merge_comparison_data(data, prev_year_data, "prev_year")
    
    # 处理预算数据
    if has_budget:
        budget_data = get_budget_comparison_data(
            company, period_start_date, period_end_date, fiscal_year, budget, base_filters
        )
        merge_comparison_data(data, budget_data, "budget")
    
    # 添加必要的 periodicity 参数
    columns = get_columns(
        period_list=period_list,
        company=company,
        periodicity=periodicity
    )
    
    # 手动添加比较列（如果需要）
    if has_prev_year:
        columns.extend(get_comparison_columns("Previous Year"))
    if has_budget:
        columns.extend(get_comparison_columns("Budget"))
    
    return columns, data

# 生成比较列
def get_comparison_columns(label):
    """生成同比或预算比较列"""
    return [
        {
            "label": f"{label} Amount",
            "fieldname": f"balance_{'prev_year' if label == 'Previous Year' else 'budget'}",
            "fieldtype": "Currency",
            "width": 150
        },
        {
            "label": f"Difference ({label})",
            "fieldname": f"difference_{'prev_year' if label == 'Previous Year' else 'budget'}",
            "fieldtype": "Currency",
            "width": 150
        },
        {
            "label": f"% Change ({label})",
            "fieldname": f"percentage_change_{'prev_year' if label == 'Previous Year' else 'budget'}",
            "fieldtype": "Float",
            "width": 150,
            "options": "Percentage"
        }
    ]

# 以下函数保持不变
def get_prev_year_period(start_date, end_date):
    """计算上一年同期的日期范围"""
    prev_year_start = frappe.utils.add_months(start_date, -12)
    prev_year_end = frappe.utils.add_months(end_date, -12)
    return prev_year_start, prev_year_end

def merge_comparison_data(main_data, comparison_data, data_type):
    """合并比较数据到主数据"""
    comparison_map = {d.get("account_name"): d for d in comparison_data}
    
    for d in main_data:
        account_name = d.get("account_name")
        comparison_row = comparison_map.get(account_name)
        
        if comparison_row:
            # 复制比较值
            for key, value in comparison_row.items():
                if key not in ["account_name", "account", "parent_account", "indent"]:
                    d[f"{key}_{data_type}"] = value
            
            # 计算差异和百分比
            current_value = d.get("balance") or 0
            comparison_value = comparison_row.get("balance") or 0
            
            d[f"difference_{data_type}"] = current_value - comparison_value
            
            if comparison_value != 0:
                d[f"percentage_change_{data_type}"] = (
                    (current_value - comparison_value) / comparison_value * 100
                )
            else:
                d[f"percentage_change_{data_type}"] = 0

def get_budget_comparison_data(company, start_date, end_date, fiscal_year, budget, filters=None):
    """从 tabBudget Account 和 tabMonthly Distribution Percentage 获取预算数据"""
    # 查询预算账户数据
    budget_accounts = frappe.db.get_all(
        "Budget Account",
        filters={
            "parent": budget,
            "parenttype": "Budget",
            "docstatus": 1
        },
        fields=["account", "budget_amount", "monthly_distribution", "cost_center"]  # 从Budget Account获取cost_center
    )
    
    # 如果有成本中心筛选，过滤预算账户
    if filters and filters.get("cost_center"):
        filtered_budget_accounts = []
        cost_centers = get_cost_centers_with_children(filters.get("cost_center"))
        for ba in budget_accounts:
            # 检查预算行的成本中心是否在筛选范围内（关键修复）
            if ba.cost_center in cost_centers:
                filtered_budget_accounts.append(ba)
        budget_accounts = filtered_budget_accounts
    
    budget_data = []
    for ba in budget_accounts:
        account_name = frappe.db.get_value("Account", ba.account, "account_name")
        if not account_name:
            continue
        
        monthly_dist = get_monthly_distribution(ba.monthly_distribution, fiscal_year)
        
        total_budget = 0
        for month, percentage in monthly_dist.items():
            if is_month_in_range(month, start_date, end_date):
                monthly_budget = ba.budget_amount * (percentage / 100)
                total_budget += monthly_budget
        
        budget_data.append({
            "account_name": account_name,
            "account": ba.account,
            "balance": total_budget
        })
    
    return budget_data

def get_monthly_distribution(monthly_distribution, fiscal_year):
    """从 tabMonthly Distribution Percentage 获取月度分配比例"""
    if not monthly_distribution:
        return {month: 8.3333 for month in ["January", "February", "March", "April", 
                                           "May", "June", "July", "August", 
                                           "September", "October", "November", "December"]}
    
    dist_data = frappe.db.get_all(
        "Monthly Distribution Percentage",
        filters={
            "parent": monthly_distribution,
            "parenttype": "Monthly Distribution"
        },
        fields=["month", "percentage_allocation"]
    )
    
    return {d["month"]: d["percentage_allocation"] for d in dist_data}

def is_month_in_range(month, start_date, end_date):
    """检查月份是否在指定的日期范围内"""
    from dateutil import parser
    import calendar
    
    year = start_date.split("-")[0]
    month_num = list(calendar.month_name).index(month)
    month_first_day = parser.parse(f"{year}-{month_num:02d}-01")
    
    start = parser.parse(start_date)
    end = parser.parse(end_date)
    
    return start <= month_first_day <= end